package com.fzx.fzwsupplysystem.activity;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;

import com.camera.Camera2Interface;
import com.camera.CameraConstant;
import com.common.Facecompare;
import com.fzx.fzwsupplysystem.R;
import com.fzx.fzwsupplysystem.bean.CardInfo;
import com.fzx.fzwsupplysystem.bean.PersonBean;
import com.fzx.fzwsupplysystem.util.AppConstant;
import com.fzx.fzwsupplysystem.util.CountTimes;
import com.fzx.fzwsupplysystem.util.ToastUtil;
import com.fzx.fzwsupplysystem.view.CountTimeTextView;

import java.io.Serializable;
import java.util.Arrays;

public class FaceCompareActivity extends BaseActivity {

    private static final String TAG = "FaceCompareActivity";

    private ImageView iv_photo;
    private CountTimeTextView tv_count;

    private TextureView mCameraInfrared;
    private TextureView mCameraColor;

    Camera2Interface mColorCamera2Interface;
    Camera2Interface mBlackCamera2Interface;

    private Bitmap mBitmap = null;

    private static final int H_FACE_SUCCESS = 101;
    private static final int H_SHOW_PRO_DIALOG = 102;
    private static final int H_HIDE_PRO_DIALOG = 103;

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case H_FACE_SUCCESS:
                    //人脸比对成功，进入下一页面
                    Intent intent = new Intent(FaceCompareActivity.this, PersonalInfoActivity.class);
                    intent.putExtra("PersonBean", (Serializable) personBean);
                    startActivity(intent);
                    break;
                case H_SHOW_PRO_DIALOG:
                    String info = (String) msg.obj;
                    showProgressDialog(false, info);
                    break;
                case H_HIDE_PRO_DIALOG:
                    hideProgressDialog();
                    break;
            }
        }
    };


    private PersonBean personBean;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_face_compare);
        Intent intent = getIntent();
        personBean = (PersonBean) intent.getSerializableExtra("PersonBean");
        initView();

    }

    private void initView() {
        iv_photo = findViewById(R.id.iv_photo);
        iv_photo.setImageBitmap(CardInfo.photoBmp);
        mCameraColor = findViewById(R.id.camera_color);
        mCameraInfrared = findViewById(R.id.camera_infrared);
        tv_count = findViewById(R.id.tv_count);

        initColorCamera(mCameraColor);
        initInfraredCamera(mCameraInfrared);
    }

    private void initColorCamera(TextureView textureView) {
        mColorCamera2Interface = new Camera2Interface(this);

        mCameraColor = textureView;
        mCameraColor.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                try {
                    mColorCamera2Interface.doStartPreView(CameraConstant.ColorCameraID, mCameraColor, mColorPreviewCallBack);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            }
        });
    }

    private void initInfraredCamera(TextureView textureView) {
        mBlackCamera2Interface = new Camera2Interface(this);

        mCameraInfrared = textureView;
        mCameraInfrared.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                try {
                    Log.i(TAG, "onSurfaceTextureAvailable: doStartPreView");
                    mBlackCamera2Interface.doStartPreView(CameraConstant.InfraredCameraID, mCameraInfrared, mInfraredPreviewCallBack);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            }
        });
    }

    Camera2Interface.PreViewCallBack mColorPreviewCallBack = new Camera2Interface.PreViewCallBack() {
        @Override
        public void onPreviewFrame(Bitmap bitmap) {
            Log.i(TAG, "onPreviewFrame: mColorPreviewCallBack " + bitmap);
        }
    };

    Camera2Interface.PreViewCallBack mInfraredPreviewCallBack = new Camera2Interface.PreViewCallBack() {
        @Override
        public void onPreviewFrame(final Bitmap bitmap) {
            Log.i(TAG, "onPreviewFrame: ");
            try {
                if (!isChecking && !isComparing) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {

                            checkFace(bitmap);
                        }
                    }).start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    };

    private boolean isChecking = false;
    private boolean isComparing = false;
    private int compareCount = 0;

    private void checkFace(Bitmap bitmap) {
        isChecking = true;
        isComparing = false;
        if (isFinishing()) {
            return;
        }
        byte[] faceFeature = Facecompare.getInstance().getFaceFeature(bitmap);
        if (faceFeature == null) {
            Log.e(TAG, "checkFace: 没有人脸");
        } else {
            Log.i(TAG, "checkFace: " + Arrays.toString(faceFeature));
            mBitmap = bitmap;
            isComparing = true;
            compareCount++;
            handler.obtainMessage(H_SHOW_PRO_DIALOG, "正在进行人脸比对，请稍后。。。").sendToTarget();
            boolean compare = faceCompare(CardInfo.photoBmp, mBitmap);

            if (compare) {
                //下一页
                Log.i(TAG, "checkFace: 比对成功");
                showToastOnUI("比对成功");
                handler.sendEmptyMessage(H_FACE_SUCCESS);
            } else {
                if (compareCount >= 3) {
                    mColorCamera2Interface.doStopCamera();
                    mBlackCamera2Interface.doStopCamera();
//                    isComparing = false;
                    //比对失败
                    Log.i(TAG, "checkFace: 比对失败");
//                    showToastOnUI("连续三次比对失败");
                    showDialogOnUI("很遗憾，身份验证失败，稍后再来尝试");
                } else {
                    showToastOnUI("比对失败，重新比对。。。");//比对不成功，请换个姿势重新尝试！
                    showFaceCompare();
                }
            }
            handler.sendEmptyMessage(H_HIDE_PRO_DIALOG);
        }
        isChecking = false;
    }

    private boolean faceCompare(Bitmap photo, Bitmap face) {
        int faceVerify = Facecompare.getInstance().faceVerify(photo, face);
        Log.i(TAG, "faceCompare: " + faceVerify);
        if (faceVerify >= 80) {
            return true;
        }
        return false;
    }

    private void showToastOnUI(final String msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ToastUtil.showToast(FaceCompareActivity.this, msg);
            }
        });
    }

    private void showDialogOnUI(final String msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showMessageDialog("温馨提示", msg, false, true);
            }
        });
    }

    private void showFaceCompare() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showYNDialog("比对不成功，请换个姿势重新尝试！", "确认", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        isComparing = false;
                    }
                }, "取消", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        hideMessageDialog();
                        gotoHome();
                    }
                });
            }
        });
    }


    @Override
    protected void onResume() {
        super.onResume();
        startTimeDown();
        if (mCameraColor != null && mCameraColor.isAvailable()) {
            mColorCamera2Interface.doStartPreView(CameraConstant.ColorCameraID, mCameraColor, null);
        }
        if (mCameraInfrared != null && mCameraInfrared.isAvailable()) {
            Log.i(TAG, "onResume: doStartPreView");
            mBlackCamera2Interface.doStartPreView(CameraConstant.InfraredCameraID, mCameraInfrared, mInfraredPreviewCallBack);
        }
        isChecking = false;
        isComparing = false;
        compareCount = 0;
    }

    @Override
    protected void onStop() {
        super.onStop();
        releaseTimeDown();
        hideProgressDialog();
        hideMessageDialog();
        handler.removeMessages(H_FACE_SUCCESS);
        handler.removeMessages(H_SHOW_PRO_DIALOG);
        handler.removeMessages(H_HIDE_PRO_DIALOG);
        mColorCamera2Interface.doStopCamera();
        mBlackCamera2Interface.doStopCamera();
    }

    private void startTimeDown() {
        tv_count.startTimeDown(AppConstant.CountTime, 1, new CountTimes.OnCountTimeListener() {
            @Override
            public void onStart(int time) {
                tv_count.setText("" + time);
            }

            @Override
            public void onTick(int time) {
                tv_count.setText("" + time);
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onFinish(int time) {
                gotoHome();
            }
        });
    }

    private void releaseTimeDown() {
        tv_count.release();
    }

    public void OnBack(View view) {
        gotoHome();
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}
